package server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import server.util.CheckWin;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * TCPServer
 *
 * @author lx
 * @date 2024-06-07 21:08
 */
public class WZQServer2 {
    public static HashMap<String, Game> gameHashMap = new HashMap<>();
//    public static HashMap<String, Socket> room = new HashMap<>();

    public static void main(String[] args) throws Exception {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(16, 16, 0, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(8), Executors.defaultThreadFactory());

        ServerSocket ss = new ServerSocket(40001);
        System.out.println("开启成功,正在监听40001端口");
        while (true) {
            Socket accept = ss.accept();
            String ip = accept.getInetAddress().getHostAddress();
            int port = accept.getPort();
            System.out.println(ip + ":" + port + "上线了");
            Game game = new Game(accept, null, null, null, new ArrayList<>());
            pool.execute(new HandleThread2(game));
        }
    }
}

class HandleThread2 extends Thread {
    private Game game;

    public HandleThread2(Game game) {
        this.game = game;
    }

    public void send(Socket s, String message) {
        try {
            OutputStream os = s.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
            dos.write(message.getBytes(StandardCharsets.UTF_8));
            dos.flush();
        } catch (Exception e) {
            System.out.println("send方法异常");
            System.out.println(e);
        }
    }


    @Override
    public void run() {
        byte[] buffer = new byte[1024];
        System.out.println("开启子线程");
        while (true) {
            try {
                InputStream is = game.getMe().getInputStream();
                DataInputStream dis = new DataInputStream(is);
                int read = dis.read(buffer);
                String message = new String(buffer, 0, read, StandardCharsets.UTF_8);
                System.out.println("收到消息:" + message);
                System.out.println("read===" + read);
                if (read != 0) {
                    JSONObject receive = JSON.parseObject(message);
                    Integer type = receive.getInteger("type");
                    //下棋
                    if (type == 0) {
                        JSONArray zb = receive.getJSONArray("zb");
                        Game otherGame = WZQServer2.gameHashMap.get(this.game.getOtherId());
                        if (game.getChessman().contains(zb) || otherGame.getChessman().contains(zb)) {
                            continue;
                        }
                        System.out.println(zb);
                        send(this.game.getMe(), message);
                        send(this.game.getOther(), message);
//                        下的棋子坐标
                        this.game.getChessman().add(zb);
                        System.out.println("发送消息成功");

                        if (CheckWin.checkWin(this.game.getChessman(), zb.getInteger(0), zb.getInteger(1))) {
                            JSONObject winJO = new JSONObject();
                            winJO.put("type", 1);
                            winJO.put("result", "win");
                            String resultWin = JSON.toJSONString(winJO);
                            send(this.game.getMe(), resultWin);
                            JSONObject loseJO = new JSONObject();
                            loseJO.put("type", 1);
                            loseJO.put("result", "lose");
                            String resultLose = JSON.toJSONString(loseJO);
                            send(this.game.getOther(), resultLose);
                        }
//                        赢了
                    } else if (type == 1) {

//                        加入房间
                    } else if (type == 2) {
                        String me_p1 = receive.getString("me");
                        String ohter_p2 = receive.getString("other");

                        Game meGame = WZQServer2.gameHashMap.get(me_p1);
                        Game otherGame = WZQServer2.gameHashMap.get(ohter_p2);

                        meGame.setOther(otherGame.getMe());
                        otherGame.setOther(meGame.getMe());
                        meGame.setId(me_p1);
                        meGame.setOtherId(ohter_p2);
                        otherGame.setId(ohter_p2);
                        otherGame.setOtherId(me_p1);
                        JSONObject joinRoom = new JSONObject();
                        joinRoom.put("type", 2);
                        String s = JSON.toJSONString(joinRoom);
                        send(meGame.getMe(), s);
                        send(otherGame.getMe(), s);
//                        创建房间
                    } else if (type == 3) {
                        JSONObject jo = new JSONObject();
                        jo.put("type", 3);
                        String room_id = UUID.randomUUID().toString();
                        jo.put("me", room_id);
                        String jo2 = JSON.toJSONString(jo);
                        send(game.getMe(), jo2);
                        game.setId(room_id);
                        WZQServer2.gameHashMap.put(room_id, game);
                    }

                }

            } catch (Exception e) {
                e.printStackTrace();
                try {
                    System.out.println(game.getMe() + "掉线");
                    game.getMe().close();
                    WZQServer2.gameHashMap.remove(game.getId());
                    JSONObject err = new JSONObject();
                    err.put("type", -1);
                    err.put("err", "您的对手已掉线");
                    String errString = JSON.toJSONString(err);
                    send(game.getOther(), errString);
                    break;
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        }
    }
}
